import React, { useState, useMemo } from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Brush, ReferenceLine } from 'recharts';
import { useDiaryStore } from '../../store/diaryStore';
import { useChartContext } from '../../contexts/ChartContext';

interface EntriesOverTimeChartProps {
  days?: number;
}

const EntriesOverTimeChart: React.FC<EntriesOverTimeChartProps> = ({ days = 30 }) => {
  const getEntriesOverTime = useDiaryStore((state) => state.getEntriesOverTime);
  const { filters, setFilters } = useChartContext();
  const [zoomDomain, setZoomDomain] = useState<[number, number] | null>(null);
  const [selectedPoint, setSelectedPoint] = useState<any>(null);
  const data = getEntriesOverTime(days);
  
  // Advanced trend analysis calculations
  const trendAnalysis = useMemo(() => {
    if (data.length < 2) return { trendData: data, regression: null, movingAvg: data };
    
    // Linear regression calculation
    const n = data.length;
    const sumX = data.reduce((sum, _, i) => sum + i, 0);
    const sumY = data.reduce((sum, d) => sum + d.entries, 0);
    const sumXY = data.reduce((sum, d, i) => sum + i * d.entries, 0);
    const sumXX = data.reduce((sum, _, i) => sum + i * i, 0);
    
    const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
    const intercept = (sumY - slope * sumX) / n;
    
    // Calculate R-squared for trend strength
    const yMean = sumY / n;
    const ssTotal = data.reduce((sum, d) => sum + Math.pow(d.entries - yMean, 2), 0);
    const ssRes = data.reduce((sum, d, i) => {
      const predicted = slope * i + intercept;
      return sum + Math.pow(d.entries - predicted, 2);
    }, 0);
    const rSquared = 1 - (ssRes / ssTotal);
    
    // Moving averages (3-day and 7-day)
    const movingAvg3 = data.map((item, index) => {
      const start = Math.max(0, index - 2);
      const end = Math.min(data.length, index + 1);
      const subset = data.slice(start, end);
      const avg = subset.reduce((sum, d) => sum + d.entries, 0) / subset.length;
      return { ...item, movingAvg3: avg };
    });
    
    const movingAvg7 = data.map((item, index) => {
      const start = Math.max(0, index - 6);
      const end = Math.min(data.length, index + 1);
      const subset = data.slice(start, end);
      const avg = subset.reduce((sum, d) => sum + d.entries, 0) / subset.length;
      return { ...item, movingAvg7: avg };
    });
    
    // Combine all trend data
    const trendData = data.map((item, index) => {
      const regression = slope * index + intercept;
      return {
        ...item,
        regression: Math.max(0, regression),
        movingAvg3: movingAvg3[index].movingAvg3,
        movingAvg7: movingAvg7[index].movingAvg7,
        trend: regression // Keep for backward compatibility
      };
    });
    
    return {
      trendData,
      regression: { slope, intercept, rSquared },
      movingAvg: movingAvg7
    };
  }, [data]);
  
  const { trendData, regression } = trendAnalysis;

  const handlePointClick = (data: any) => {
    setSelectedPoint(data);
    // Set date range filter for the clicked day
    const clickedDate = new Date(data.payload.fullDate || data.payload.date);
    const startDate = clickedDate.toISOString().split('T')[0];
    const endDate = startDate;
    setFilters({ dateRange: { start: new Date(startDate), end: new Date(endDate) } });
  };

  const handleBrushChange = (brushData: any) => {
    if (brushData && brushData.startIndex !== undefined && brushData.endIndex !== undefined) {
      const startDate = data[brushData.startIndex]?.date;
      const endDate = data[brushData.endIndex]?.date;
      if (startDate && endDate) {
        setFilters({ 
          dateRange: { 
            start: new Date(startDate), 
            end: new Date(endDate) 
          } 
        });
      }
    }
  };

  const resetZoom = () => {
    setZoomDomain(null);
    setFilters({ dateRange: null });
    setSelectedPoint(null);
  };

  if (data.length === 0) {
    return (
      <div className="bg-white rounded-lg shadow-sm border border-warm-gray-200 p-6">
        <h3 className="text-lg font-semibold text-warm-gray-800 mb-4">
          Entries Over Time (Last {days} Days)
        </h3>
        <div className="flex items-center justify-center h-64 text-warm-gray-500">
          <p>No data available</p>
        </div>
      </div>
    );
  }

  const maxEntries = Math.max(...data.map(d => d.entries));
  const avgEntries = data.reduce((sum, d) => sum + d.entries, 0) / data.length;

  return (
    <div className="bg-white rounded-lg shadow-sm border border-warm-gray-200 p-6">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-lg font-semibold text-warm-gray-800">
          Entries Over Time (Last {days} Days)
        </h3>
        <div className="flex items-center gap-2">
          {filters.dateRange && (
            <button
              onClick={resetZoom}
              className="text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded hover:bg-blue-200 transition-colors"
            >
              Reset Zoom
            </button>
          )}
          <div className="text-xs text-warm-gray-500">
            Avg: {avgEntries.toFixed(1)} entries/day
          </div>
        </div>
      </div>
      
      {selectedPoint && (
        <div className="mb-3 p-2 bg-green-50 rounded-lg">
          <div className="flex items-center justify-between">
            <span className="text-sm font-medium text-green-800">
              Selected: {selectedPoint.date} ({selectedPoint.entries} entries)
            </span>
            <button
              onClick={() => setSelectedPoint(null)}
              className="text-xs text-green-600 hover:text-green-800 underline"
            >
              Clear
            </button>
          </div>
        </div>
      )}
      
      <ResponsiveContainer width="100%" height={350}>
        <LineChart data={trendData} onClick={handlePointClick}>
          <CartesianGrid strokeDasharray="3 3" stroke="#f3f4f6" />
          <XAxis 
            dataKey="date" 
            stroke="#6b7280"
            fontSize={12}
            tickLine={false}
            domain={zoomDomain || ['dataMin', 'dataMax']}
          />
          <YAxis 
            stroke="#6b7280"
            fontSize={12}
            tickLine={false}
            axisLine={false}
          />
          <Tooltip 
            contentStyle={{
              backgroundColor: '#ffffff',
              border: '1px solid #e5e7eb',
              borderRadius: '8px',
              boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)'
            }}
            content={({ active, payload, label }) => {
              if (active && payload && payload.length) {
                const data = payload[0].payload;
                return (
                  <div className="bg-white p-3 border border-warm-gray-200 rounded-lg shadow-lg">
                    <p className="font-medium text-warm-gray-800">{label}</p>
                    <p className="text-sm text-green-600">
                      Entries: {data.entries}
                    </p>
                    <p className="text-sm text-blue-600">
                      Regression: {data.regression?.toFixed(1) || 'N/A'}
                    </p>
                    <p className="text-sm text-purple-600">
                      3-day avg: {data.movingAvg3?.toFixed(1) || 'N/A'}
                    </p>
                    <p className="text-sm text-orange-600">
                      7-day avg: {data.movingAvg7?.toFixed(1) || 'N/A'}
                    </p>
                    <p className="text-xs text-gray-500 mt-1">
                      Click to filter by this date
                    </p>
                  </div>
                );
              }
              return null;
            }}
          />
          <ReferenceLine y={avgEntries} stroke="#f59e0b" strokeDasharray="5 5" label="Average" />
          <Line 
            type="monotone" 
            dataKey="entries" 
            stroke="#059669" 
            strokeWidth={2}
            dot={{ fill: '#059669', strokeWidth: 2, r: 4, cursor: 'pointer' }}
            activeDot={{ r: 6, fill: '#047857', cursor: 'pointer' }}
          />
          <Line 
            type="monotone" 
            dataKey="regression" 
            stroke="#3b82f6" 
            strokeWidth={2}
            strokeDasharray="5 5"
            dot={false}
            name="Regression Line"
          />
          <Line 
            type="monotone" 
            dataKey="movingAvg3" 
            stroke="#8b5cf6" 
            strokeWidth={1}
            strokeDasharray="2 2"
            dot={false}
            name="3-day Moving Average"
          />
          <Line 
            type="monotone" 
            dataKey="movingAvg7" 
            stroke="#f59e0b" 
            strokeWidth={1}
            strokeDasharray="4 2"
            dot={false}
            name="7-day Moving Average"
          />
          <Brush 
            dataKey="date" 
            height={30} 
            stroke="#059669"
            onChange={handleBrushChange}
          />
        </LineChart>
      </ResponsiveContainer>
      
      {/* Trend Analysis Summary */}
      {regression && (
        <div className="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
          <div className="bg-blue-50 p-3 rounded-lg">
            <h4 className="font-medium text-blue-800 mb-1">Trend Direction</h4>
            <p className="text-blue-700">
              {regression.slope > 0.1 ? '📈 Increasing' : 
               regression.slope < -0.1 ? '📉 Decreasing' : 
               '➡️ Stable'}
            </p>
            <p className="text-xs text-blue-600 mt-1">
              Slope: {regression.slope.toFixed(3)} entries/day
            </p>
          </div>
          
          <div className="bg-purple-50 p-3 rounded-lg">
            <h4 className="font-medium text-purple-800 mb-1">Trend Strength</h4>
            <p className="text-purple-700">
              {regression.rSquared > 0.7 ? '💪 Strong' : 
               regression.rSquared > 0.4 ? '👍 Moderate' : 
               '🤏 Weak'}
            </p>
            <p className="text-xs text-purple-600 mt-1">
              R² = {regression.rSquared.toFixed(3)}
            </p>
          </div>
          
          <div className="bg-green-50 p-3 rounded-lg">
            <h4 className="font-medium text-green-800 mb-1">Consistency</h4>
            <p className="text-green-700">
              {avgEntries > 1 ? '✅ Regular' : 
               avgEntries > 0.5 ? '⚠️ Occasional' : 
               '❌ Infrequent'}
            </p>
            <p className="text-xs text-green-600 mt-1">
              {avgEntries.toFixed(1)} entries/day avg
            </p>
          </div>
        </div>
      )}
    </div>
  );
};

export default EntriesOverTimeChart;